using System;
using System.Collections.Generic;
using System.Data;
using System.Security;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;

using Microsoft.SharePoint;
using Microsoft.SharePoint.Publishing.Navigation;
using Microsoft.SharePoint.Utilities;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.IO;
using System.Xml;
using System.Reflection;
using System.Collections.Specialized;
using System.Collections;

namespace CoolStuffs.Sharepoint.Webparts.RecentItems.FeatureEvents
{
    /// <summary>
    /// For Removing the Webpart from Web Part Gallery when the the Feature is Deactivated
    /// </summary>
    public class WebFeatureReciever : SPFeatureReceiver
    {
        #region Nested Enums/Structures/Classes

        #region Public
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Member Variables

        #region Public
        #endregion

        #region Protected
        #endregion

        #region Private
        /// <summary>
        /// This Constant Stores the Query  for Retrieving the Recent Documents Item From Web Part Gallery
        /// </summary>
        private System.String _typeName = String.Empty;
        private const System.String _camlQuery = "<Where> <Eq><FieldRef Name='Title'/>" +
                                              "<Value Type='Text'>Recent Documents</Value></Eq></Where>";
        private const System.String _attributeName = "name";
        Dictionary<string, string> _currentAssemblyAttributeCollection = default(Dictionary<string, string>);
      
        /// <summary>
        /// This Constant Stores the URL of Webpart Gallery
        /// </summary>
        private const System.String _url = "/_catalogs/wp/Forms/AllItems.aspx";
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Constructors/Destructors

        #region Public

        public WebFeatureReciever()
        {
            _currentAssemblyAttributeCollection = new Dictionary<string,string>();
            Assembly _currentAssemblyInfo = Assembly.GetExecutingAssembly();
            Type _webpartType = typeof(DocumentsAggregator);
            StringBuilder _typeFullName = new StringBuilder();
            _typeFullName.Append(_webpartType.Namespace);
            _typeFullName.Append(".");
            _typeFullName.Append(_webpartType.Name);
            _typeName = _typeFullName.ToString() + ", " + _currentAssemblyInfo.FullName;
        }
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Properties

        #region Public
        #endregion

        #region Protected
        #endregion

        #region Private
        #endregion

        #region Internal
        #endregion

        #endregion

        #region Methods

        #region Public
        /// <summary>
        /// Not Implemented
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureActivated(SPFeatureReceiverProperties properties)
        {
        }


        /// <summary>
        /// Find the Recent Document Item from the Webpart Gallery List and Delete it
        /// </summary>
        /// <param name="properties">Properties related with the Feature to be Deactivated</param>
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
            SPSite _site = (SPSite)properties.Feature.Parent;
            SPWeb _web = _site.RootWeb;
            SPDocumentLibrary _list;
            /* This is not th Right way of doing this */
            //_list = (SPDocumentLibrary)_web.GetListFromUrl(_url);
            
            // This is better
            _list = (SPDocumentLibrary)_site.GetCatalog(SPListTemplateType.WebPartCatalog);

            int counter = 0;
            while (counter < _list.ItemCount)
            {
                SPListItem _currentItem = _list.Items[counter];
                Stream _stream = _currentItem.File.OpenBinaryStream();
                if (_stream != null)
                {
                    _stream.Position = 0;
                    XmlDocument _webpartXml = new XmlDocument();
                    _webpartXml.LoadXml(new StreamReader(_stream).ReadToEnd());

                    if (getValueRecursive(_webpartXml.DocumentElement.ChildNodes, 
                        _attributeName, _typeName))
                    {
                        // we have found our assembly
                        _currentItem.Delete();
                        break;
                    }
                    else
                    {
                        counter++;
                    }
                }
            }
            _list.Update();
        }

        /// <summary>
        /// Not Implemented
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureInstalled(SPFeatureReceiverProperties properties)
        {
        }

        /// <summary>
        /// Not Implemented
        /// </summary>
        /// <param name="properties"></param>
        public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
        {
        }
        #endregion

        #region Protected
        #endregion

        #region Private
        /// <summary>
        /// Recursive function to check whether or not
        /// the element has the fed attribute value
        /// </summary>
        /// <param name="NodeList">XmlNodelist to work this on</param>
        /// <param name="attr">attribute we are looking at</param>
        /// <param name="value">its value</param>
        /// <returns>TRUE/FALSE</returns>
        private static bool getValueRecursive(XmlNodeList NodeList, string attr, string value)
        {
            foreach (XmlNode node in NodeList)
            {
                if (node.Attributes != null)
                {
                    if (node.Attributes[attr] != null)
                    {
                        if (node.Attributes[attr].Value.ToLower().Contains(value.ToLower()))
                            return true;
                        else
                            return getValueRecursive(node.ChildNodes, attr, value);
                    }
                }
                return getValueRecursive(node.ChildNodes, attr, value);

            }

            return false;
        }
        #endregion

        #region Internal
        #endregion

        #endregion
    }
}
